<template>
  <Dialog
    v-model="dialogVisible"
    :title="dialogTitle"
    :width="1500"
    class="bug-info"
    :close-on-click-modal="false"
    @full-screen="handleFullScreenChange"
  >
    <el-form
      ref="formRef"
      v-loading="formLoading"
      :model="formData"
      label-width="100px"
      class="form-inline"
      :disabled="true"
    >
      <div class="base">
        <header>基本属性:</header>
        <el-form-item label="版本:" prop="projectVersionId">
          <el-select
            v-model="formData.projectVersionId"
            clearable
            filterable
            placeholder="请选择版本"
          >
            <el-option
              v-for="item in versionList"
              :key="item.id"
              :label="item.versionName"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="报告员:" prop="creator">
          <el-select
            v-model="formData.creator"
            filterable
            clearable
            placeholder="请选择报告员"
            :disabled="true"
          >
            <el-option
              v-for="item in memberList"
              :key="item.memberId"
              :label="item.memberName"
              :value="item.memberId + ''"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="指派人:" prop="developer">
          <el-select
            v-model="formData.developer"
            clearable
            placeholder="请选择指派人"
            :disabled="disabledPermission"
            filterable
          >
            <el-option
              v-for="item in memberList"
              :key="item.memberName"
              :label="item.memberName"
              :value="item.memberName"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="问题类型:" prop="bugType">
          <el-select v-model="formData.bugType" clearable placeholder="请选择问题类型">
            <el-option
              v-for="item in getIntDictOptions(DICT_TYPE.BUG_TYPE)"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="严重级别:" prop="bugLevel">
          <el-select v-model="formData.bugLevel" clearable placeholder="请选择严重级别">
            <el-option
              v-for="item in getIntDictOptions(DICT_TYPE.BUG_LEVEL)"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="状态:" prop="bugStatus">
          <el-select v-model="formData.bugStatus" clearable placeholder="请选择状态">
            <el-option
              v-for="item in statusList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="优先级:" prop="bugPriority">
          <el-select v-model="formData.bugPriority" clearable placeholder="请选择优先级">
            <el-option
              v-for="item in getIntDictOptions(DICT_TYPE.PRIORITY)"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="出现频率:" prop="bugProbability">
          <el-select v-model="formData.bugProbability" clearable placeholder="请选择出现频率">
            <el-option
              v-for="item in getIntDictOptions(DICT_TYPE.PROBABILITY)"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="测试计划:" prop="testPlanId">
          <el-select
            v-model="formData.testPlanId"
            filterable
            placeholder="请选择测试计划"
            @change="getTestCasesList"
          >
            <el-option
              v-for="item in testPlanList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="提测版本:" prop="requestFormId">
          <el-select v-model="formData.requestFormId" placeholder="请选择提测版本" filterable>
            <el-option
              v-for="item in commitList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="测试用例集:" prop="testPlanCasesId">
          <el-tree-select
            v-model="formData.testPlanCasesId"
            :data="testPlanCasesList"
            check-strictly
            :props="{ label: 'name', value: 'id' }"
            filterable
            node-key="id"
            @change="getTestCasesList"
            placeholder="请选择测试用例集"
            :render-after-expand="false"
          />
        </el-form-item>
        <el-form-item label="对应用例:" prop="testCaseId" v-if="formData.testPlanId">
          <el-select
            v-model="formData.testCaseId"
            multiple
            placeholder="请选择对应用例"
            filterable
            clearable
          >
            <el-option
              v-for="item in testCasesList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item
          label="影响域分析:"
          prop="bugInfluence"
          style="width: 96%"
          v-if="isShowReason"
        >
          <el-input
            v-model="formData.bugInfluence"
            placeholder="请输入影响域分析"
            type="textarea"
          />
        </el-form-item>
        <el-form-item label="问题原因:" prop="bugReason" style="width: 96%" v-if="isShowReason">
          <el-input v-model="formData.bugReason" placeholder="请输入问题原因" type="textarea" />
        </el-form-item>
        <el-form-item label="解决措施:" prop="bugSolution" style="width: 96%" v-if="isShowReason">
          <el-input v-model="formData.bugSolution" placeholder="请输入解决措施" type="textarea" />
        </el-form-item>
        <el-form-item label="关闭版本:" prop="closeVersionId" v-if="isShowCloseVersion">
          <el-select v-model="formData.closeVersionId" placeholder="请选择关闭版本" filterable>
            <el-option
              v-for="item in commitList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="测试环境:" prop="environment">
          <el-input v-model="formData.environment" placeholder="请输入测试环境" />
        </el-form-item>
      </div>
      <div class="desc">
        <header>问题描述:</header>
        <el-form-item label="问题描述:" prop="description" style="width: 100%">
          <el-input
            v-model="formData.description"
            placeholder="请输入问题描述"
            type="textarea"
            rows="5"
          />
        </el-form-item>
        <el-form-item label="问题详情:" prop="bugDetails" style="width: 100%">
          <el-input
            v-model="formData.bugDetails"
            placeholder="请输入问题详细信息，包括问题复现步骤"
            type="textarea"
            rows="8"
          />
        </el-form-item>
        <el-form-item label="附件:" prop="file" class="upload-wrap">
          <div class="gap-2 file-wrap">
            <template v-if="fileList && fileList.length">
              <div v-for="item of viewDocFiles" :key="item.name" class="file-view">
                <el-tag type="primary">{{ item.name }} </el-tag>
                <span class="btn" @click="handleView(item.url)">预览</span
                ><span class="btn" @click="download(item)">下载</span>
              </div>
              <viewFile :file-list="viewImgFiles" />
            </template>
            <span v-else>暂无附件</span>
          </div>
        </el-form-item>
      </div>
    </el-form>
    <div class="log">
      <header>问题日志: </header>
      <el-table :data="activities" :show-overflow-tooltip="true" :height="height">
        <el-table-column align="center" label="日期" prop="createTime" :formatter="dateFormatter" />
        <el-table-column align="center" label="问题活动" prop="bugOperation" />
        <el-table-column align="center" label="成员" prop="creator">
          <template #default="scope">
            <span>{{ findName(scope.row.creator) }}</span>
          </template>
        </el-table-column>
        <el-table-column align="center" label="操作">
          <template #default="scope">
            <el-button link type="primary" @click="handleAddLog(scope.row)"> 详情 </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <template #footer>
      <el-button @click="dialogVisible = false">关 闭 </el-button>
    </template>
  </Dialog>

  <!-- 日志详情 -->
  <el-drawer v-model="dialogLog" title="详情" direction="rtl" class="demo-drawer" v-if="dialogLog" :size="600">
    <div class="demo-drawer__content">
      <el-form :model="form" ref="logFormRef">
        <el-form-item label="描述:" prop="bugOperation">
          <span>{{ form.bugOperation }}</span>
        </el-form-item>
        <el-form-item label="附件:" prop="bugEnclosure">
          <div class="gap-2 file-wrap">
            <template v-if="fileListLog && fileListLog.length">
              <div v-for="item of viewDocLogFiles" :key="item.name" class="file-view">
                <el-tag type="primary">{{ item.name }} </el-tag>
                <el-button class="btn" @click="handleView(item.url)" size="small">预览</el-button
                ><el-button class="btn" @click="download(item)" size="small">下载</el-button>
              </div>
              <viewFile :file-list="viewImgLogFiles" />
            </template>
            <span v-else>暂无附件</span>
          </div>
        </el-form-item>
      </el-form>
      <div class="demo-drawer__footer">
        <el-button @click="dialogLog = false">关闭</el-button>
      </div>
    </div>
  </el-drawer>
</template>
<script lang="ts" setup>
defineOptions({ name: 'UpdateForm' })
import { getDefectInfo, getDefectLogList } from '@/api/defect'
import { useAppStore } from '@/store/modules/app'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { getTestboxTree, getTestformList, getPage } from '@/api/usecase'
import { getProjectMemberList } from '@/api/project'
import { getDemandList, getProjectMemberRole } from '@/api/demand'
import { downloadByUrl1 } from '@/utils/filt'
import { useUserStore } from '@/store/modules/user'
import { getAccessToken } from '@/utils/auth'
import { getPlanList, getCaseList, getCaseListByName } from '@/api/testPlan'
import { dateFormatter } from '@/utils/formatTime'
import viewFile from '../defectManage/component/ViewImgFileCom.vue'

const userStore = useUserStore()
const userName = computed(() => userStore.user.nickname ?? '')
const userId = computed(() => userStore.user.id ?? '')
const appStore = useAppStore()
const projectId = computed(() => appStore.getSelectProject)
const { t } = useI18n()
const message = useMessage()
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref('')
const formData = ref({} as any)
const formRef = ref() // 表单 Ref
const memberList = ref([] as any) // 用户列表
const versionList = ref([] as any) // 版本列表
const testPlanCasesList = ref([] as any) // 测试用例集
const testCasesList = ref([] as any) // 测试用例集
const fileList = ref([] as any) // 问题文件列表
const isShowReason = ref(false)
const isShowCloseVersion = ref(false)
const role = ref('')
const commitList = ref([] as any)
const testPlanList = ref([] as any) // 测试计划
const activities = ref([] as any) //日志列表
const height = ref('500px') // 表格高度
const dialogLog = ref(false) // 日志弹窗
const form = ref({} as any) // 新增问题日志表单
const fileListLog = ref([] as any) // 日志文件列表
const logFormRef = ref() //日志表单ref
const viewImgFiles = ref([] as any)
const viewDocFiles = ref([] as any)
const viewImgLogFiles = ref([] as any)
const viewDocLogFiles = ref([] as any)
const statusList = computed(() => {
  const list = getIntDictOptions(DICT_TYPE.BUG_STATUS)
  if (['projectManager', 'developer'].includes(role.value)) {
    return list.filter((l) => l.label.indexOf('已关闭') == -1)
  }
  return list
})
/** 打开弹窗 */
const open = async (type: string, id: string) => {
  dialogVisible.value = true
  dialogTitle.value = '问题详情'
  formType.value = type
  isShowReason.value = false
  isShowCloseVersion.value = false
  formLoading.value = true
  getProjectMemberRoleFn()
  resetForm()
  getMembers()
  getVersion()
  getTestPlan()
  getTestPlanCasesList()
  getCommitList()
  // 修改时，设置数据
  if (id) {
    try {
      getLogs(id)
      let data = await getDefectInfo({ id })
      await getTestCasesList(data)
      formData.value = data
      fileList.value = JSON.parse(data.bugEnclosure)
      filterImageAndNonImageFiles(fileList.value, 'info')
      isShowReason.value = data.bugStatus == 2
      isShowCloseVersion.value = data.bugStatus == 7
    } finally {
      formLoading.value = false
    }
  }
}

function filterImageAndNonImageFiles(filesArray, type) {
  viewImgFiles.value = []
  viewImgLogFiles.value = []
  viewDocFiles.value = []
  viewDocLogFiles.value = []
  filesArray.forEach((file) => {
    if (isImageFile(file)) {
      type == 'info' ? viewImgFiles.value.push(file) : viewImgLogFiles.value.push(file)
    } else {
      type == 'info' ? viewDocFiles.value.push(file) : viewDocLogFiles.value.push(file)
    }
  })
}
// 判断文件是否为图片的辅助函数
function isImageFile(file) {
  const fileName = file.name
  const fileExtension = fileName.split('.').pop().toLowerCase()
  const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
  return imageExtensions.includes(fileExtension)
}
// 新增日志
const handleAddLog = (data?) => {
  dialogLog.value = true
  resetFormLog()
  if (data) {
    form.value = data
    fileListLog.value = JSON.parse(data.bugEnclosure)
    filterImageAndNonImageFiles(fileListLog.value, 'log')
  }
}
// 重置日志表单
const resetFormLog = () => {
  form.value = {
    bugOperation: '',
    bugEnclosure: ''
  }
  fileListLog.value = []
  logFormRef.value?.resetFields()
}
// 查找name
const findName = (id) => {
  const result = memberList.value.find((k) => k.memberId == id)
  if (result) {
    return result.memberName
  }
  return '-'
}
// 弹窗全屏
const handleFullScreenChange = (val) => {
  if (val) {
    const windowHeight = document.documentElement.offsetHeight
    height.value = `${windowHeight - 200}px`
  } else {
    height.value = `calc(100% - 20px)`
  }
}
/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: '',
    description: '',
    bugType: 1,
    bugLevel: 2,
    bugStatus: 1,
    bugPriority: 3,
    bugProbability: 7,
    projectVersionId: '',
    testPlanId: '',
    testPlanCasesId: '',
    testCaseId: [],
    developer: '',
    creator: userName.value,
    bugDetails: '',
    bugEnclosure: '',
    bugInfluence: '',
    bugReason: '',
    bugSolution: '',
    closeVersionId: '',
    requestFormId: '',
    environment: 'Windows 10',
    projectId: projectId.value
  }
  fileList.value = []
  formRef.value?.resetFields()
}

defineExpose({ open }) // 提供 open 方法，用于打开弹窗

// 获取测试计划
const getTestPlan = async () => {
  let data = await getPlanList({ projectId: projectId.value })
  testPlanList.value = data
}
// 获取提测单
const getCommitList = async () => {
  commitList.value = []
  let data = await getTestformList({
    projectId: projectId.value
  })
  commitList.value = data.map((item) => {
    return {
      label: `${item.version.versionName}版本-${item.rounds}轮次`,
      value: item.id
    }
  })
}

// 获取测试用例集
const getTestPlanCasesList = async () => {
  let data = await getTestboxTree({ projectId: projectId.value })
  testPlanCasesList.value = data ? [data] : []
}

// 获取对应用例
const getTestCasesList = async (val) => {
  const params = {
    projectId: projectId.value,
    testSuiteId: val.testPlanCasesId,
    testPlanId: val.testPlanId
  }
  let data = await getCaseListByName(params)
  testCasesList.value = data
}

// 获取成员列表
const getMembers = async () => {
  let data = await getProjectMemberList({
    pageNo: 1,
    pageSize: 100,
    projectId: projectId.value
  })
  memberList.value = data
}

// 获取版本列表
const getVersion = async () => {
  let data = await getDemandList({
    pageNo: 1,
    pageSize: 100,
    projectId: projectId.value
  })
  versionList.value = data.list
}

// 下载
const download = (val) => {
  if (!val || !val.url) {
    message.warning('无连接')
    return
  }
  downloadByUrl1({ url: val.url, fileName: val.name })
}
// 预览
const handleView = (url) => {
  if (!url) {
    message.warning('无链接')
    return
  }
  window.open(`${url}?token=Bearer ${getAccessToken()}`, '_blank')
}
// 获取人员在项目中角色
const getProjectMemberRoleFn = async () => {
  let data = await getProjectMemberRole({ projectId: projectId.value })
  role.value = data
}
// 日志列表
const getLogs = async (id) => {
  let data = await getDefectLogList({ id })
  activities.value = data
}
</script>

<style lang="scss">
.bug-info {
  .case-item {
    .el-form-item__label {
      padding: 0 22px 0 0;
    }
    .el-icon.el-tooltip__trigger {
      position: absolute;
      left: -18px;
    }
  }

  .fullscreen {
    position: fixed !important;
    left: 5% !important;
    top: 5% !important;
    width: 90% !important;
    height: 90% !important;
    object-fit: contain !important;
    z-index: 9999 !important;
  }

  .close-button {
    position: absolute;
    top: -10px;
    right: -10px;
    background-color: rgba(0, 0, 0, 0.5);
    color: white;
    border: none;
    padding: 5px 10px;
    cursor: pointer;
    font-weight: bold;
    border-radius: 50%;
  }

  .upload-wrap {
    .el-form-item__content {
      display: flex;
      justify-content: left;
      align-items: flex-start;
    }
  }

  .paste {
    padding: 10px;
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    box-sizing: border-box;
    text-align: center;
    cursor: pointer;
    position: relative;
    overflow: auto;
    margin-left: 10px;
    min-height: 145px;
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;

    &-img {
      position: relative;
      margin-right: 15px;
      display: inline-block;
      width: 100px;
      height: 100px;
      margin-bottom: 5px;

      .el-image {
        width: 100%;
        height: 100%;
      }

      .el-button {
        position: absolute;
        right: -10px;
        top: -10px;
        display: none;
        background-color: rgba(0, 0, 0, 0.5);
        color: white;
        border: none;
        padding: 5px 10px;
        cursor: pointer;
        font-weight: bold;
        border-radius: 50%;
      }

      &:hover {
        .el-button {
          display: block;
        }
      }
    }
  }

  .el-form {
    display: flex;
    justify-content: space-between;
    width: 100%;
  }

  .el-dialog__body {
    display: flex;
    justify-content: space-between;
  }

  .avatar-uploader .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }

  header {
    font-weight: bold;
    margin-bottom: 10px;
    margin-left: 13px;
  }

  .base {
    padding: 10px 0 0;
    margin-bottom: 10px;
  }

  .desc {
    padding: 10px 30px 0 0;
    margin-bottom: 10px;
    margin-left: 20px;
    flex: 1;
  }

  .log {
    flex: 1;
    min-width: 500px;
    header {
      display: flex;
      justify-content: space-between;
    }
  }

  :deep(.el-collapse-item__header) {
    font-weight: bold;
  }

  .avatar-uploader .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
  }

  .avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
  }

  .el-icon.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    text-align: center;
  }

  .form-inline .el-input {
    --el-input-width: 180px;
  }

  .form-inline .el-select {
    --el-select-width: 180px;
  }
}

.file-view {
  .btn {
    margin: 0 5px;
    display: inline-block;
    cursor: pointer;
    height: 24px;
    line-height: 13px;
    padding: 5px 11px;
    font-size: 12px;
    border-radius: 4px;
    box-sizing: border-box;
    border: 1px solid #dcdfe6;

    &:hover {
      color: #409eff;
      border-color: #c6e2ff;
      background-color: #ecf5ff;
      outline: 0;
    }
  }
}
</style>
